using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Formatting;
using BasicallyNot.CodeTransformers.Transformers;


namespace BasicallyNot.CodeTransformers
{

	internal class CodeTransformerManager
	{

		internal IWpfTextView View { get; private set; }
		internal IAdornmentLayer Layer { get; private set; }

		internal double FontSize { get; private set; }
		internal FontFamily FontFamily { get; private set; }
		internal Brush EditorBackground { get; private set; }
		internal Brush CurlyBracketForeground { get; private set; }
		internal Brush KeywordForeground { get; private set; }

		private ViewFormatManager _viewFormatManager = new ViewFormatManager();
		private IList<BaseCodeTransformer> _transformers = new List<BaseCodeTransformer>();

		internal CodeTransformerManager( IWpfTextView view, IEditorFormatMap editorFormatMap )
		{
			View = view;
			Layer = view.GetAdornmentLayer( "CodeTransformerManager" );

			SetTextDefaults();
			SetTextProperties( editorFormatMap );
			editorFormatMap.FormatMappingChanged += OnFormatMappingChanged;

			_transformers.Add( new VisualTransformer( this ) );

			// listen to any event that changes the layout (text changes, scrolling, etc)
			view.LayoutChanged += OnLayoutChanged;
		}



		#region Fonts and Colors

		private void SetTextDefaults()
		{
			FontFamily = new FontFamily( "Consolas" );
			FontSize = 10;

			CurlyBracketForeground = new SolidColorBrush( Color.FromArgb( 0x30, 0x00, 0x00, 0x00 ) );
			KeywordForeground = new SolidColorBrush( Color.FromArgb( 0xFF, 0x00, 0x00, 0x00 ) );
			EditorBackground = new SolidColorBrush( Colors.White );
		}



		private void SetCurlyBracketForeground()
		{
			Brush curlyBracketForeground = _viewFormatManager.GetProperty( StyleOffset.Foreground, "Plain Text" );
			if ( curlyBracketForeground != null )
				CurlyBracketForeground = curlyBracketForeground;
		}



		private void SetKeywordForeground()
		{
			Brush keywordForeground = _viewFormatManager.GetProperty( StyleOffset.Foreground, "Keyword" );
			if ( keywordForeground != null ) {
				KeywordForeground = keywordForeground;
				KeywordForeground.Opacity = 0.3;
			}
		}



		private void SetEditorBackground()
		{
			Brush editorBackground = _viewFormatManager.GetProperty( StyleOffset.Background, "Plain Text" );
			if ( editorBackground != null ) {
				EditorBackground = editorBackground;
				return;
			}

			editorBackground = _viewFormatManager.GetProperty( StyleOffset.Background, "TextView Background" );
			if ( editorBackground != null ) {
				EditorBackground = editorBackground;
				return;
			}
		}

		#endregion



		private void SetTextProperties( IEditorFormatMap formats )
		{
			_viewFormatManager.Formats = formats;

			SetCurlyBracketForeground();
			SetKeywordForeground();
			SetEditorBackground();
		}



		private void OnFormatMappingChanged( object sender, FormatItemsEventArgs e )
		{
			IEditorFormatMap formatMap = sender as IEditorFormatMap;
			if ( formatMap != null )
				SetTextProperties( formatMap );
		}



		private void OnLayoutChanged( object sender, TextViewLayoutChangedEventArgs e )
		{
			foreach ( ITextViewLine line in e.NewOrReformattedLines ) {
				foreach ( BaseCodeTransformer xfrm in _transformers ) {
					if ( xfrm.Transform( line ) )
						break;
				}
			}
		}

	}
}
